home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / kriegspi / connect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-30  |  4.3 KB  |  195 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: connect.c,v 1.5 87/05/19 17:24:26 schoch Exp $";
  3. #endif
  4.  
  5. #include "externs.h"
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/param.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #include <pwd.h>
  12. #include <errno.h>
  13.  
  14. extern int errno;
  15.  
  16. int sock;    /* in main */
  17. FILE *inp, *out;
  18.  
  19. connectport (opponent, port)
  20.     char *opponent;
  21.     u_short port;
  22. {
  23.     struct sockaddr_in addr;
  24.     struct hostent *host;
  25.     struct passwd *mypasswd, *getpwuid();
  26.     char *hishostname, *myname, *index(), *getpw(), *malloc();
  27.     char myhostname[MAXHOSTNAMELEN+1];
  28.     char *hisaddr, *myaddr;
  29.     int hislen, mylen;
  30.     u_long iaddr;
  31.     uid_t getuid();
  32.     u_short hashport(), hashaddr();
  33.     char *copyhost();
  34.     int s, i;
  35.  
  36.     if (gethostname (myhostname, MAXHOSTNAMELEN) < 0)
  37.         error ("gethostname in connectport");
  38.     host = gethostbyname(myhostname);
  39.     if (host == NULL) {
  40.         errno = 0;
  41.         error("don't know my own name.");
  42.     }
  43.     mylen = host->h_length;
  44.     myaddr = copyhost(host);
  45.     if (hishostname = index (opponent, '@')) {
  46.         *hishostname++ = '\0';        /* separate user and host */
  47.         if (hishostname[0] >= '0' && hishostname[0] <= '9') {
  48.             iaddr = inet_addr(hishostname);
  49.             hisaddr = (char *)&iaddr;
  50.             hislen = sizeof iaddr;
  51.         } else {
  52.             host = gethostbyname(hishostname);
  53.             if (host == NULL) {
  54.                 errno = 0;
  55.                 error("Unknown host");
  56.             }
  57.             hislen = host->h_length;
  58.             hisaddr = copyhost(host);
  59.             hishostname = host->h_name;
  60.         }
  61.     } else {
  62.         hislen = mylen;
  63.         hisaddr = myaddr;
  64.         hishostname = myhostname;
  65.     }
  66.     mypasswd = getpwuid ((int) getuid());
  67.     myname = mypasswd -> pw_name;
  68.     if (iamserver == UNSET)
  69.         if (i = strcmp (myname, opponent))
  70.             iamserver = (i < 0);
  71.         else if (i = comparehost(myaddr, hisaddr, mylen))
  72.             iamserver = (i < 0);
  73.     if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  74.         error ("socket in connectport");
  75.     bzero ((char *) &addr, sizeof (addr));
  76.     if (port != 0) {
  77.         if (port > 1000) {
  78.             errno = 0;
  79.             error ("bad port number");
  80.         }
  81.     } else if (iamserver) {
  82.         port = hashaddr(myaddr, port, mylen);
  83.         port = hashaddr(hisaddr, port, hislen);
  84.         port = hashport(myname, port);
  85.         port = hashport(opponent, port);
  86.     } else {
  87.         port = hashaddr(hisaddr, port, hislen);
  88.         port = hashaddr(myaddr, port, mylen);
  89.         port = hashport(opponent, port);
  90.         port = hashport(myname, port);
  91.     }
  92.     port += 3000;
  93.     addr.sin_family = AF_INET;
  94.     addr.sin_port = htons (port);
  95.     if (iamserver) {
  96.         s = sock;
  97.         if (bind (s, /*(char *)*/ &addr, sizeof (addr)) < 0)
  98.             if (errno == EADDRINUSE && iamserver == UNSET) {
  99.                 /* hope other player is server */
  100.                 iamserver = FALSE;
  101.                 close (s);
  102.                 if ((sock = socket (AF_INET, SOCK_STREAM, 0))
  103.                     < 0)
  104.                     error ("socket in connectport");
  105.             } else
  106.                 error ("bind in connectport");
  107.         if (iamserver) {
  108.             if (listen (s, 1) < 0)
  109.                 error ("listen in connectport");
  110.             while ((sock = accept (s, (struct sockaddr_in *) NULL,
  111.                 (int *) NULL)) < 0)
  112.                 if (errno != EINTR)
  113.                     error ("accept in connectport");
  114.             close(s);
  115.         }
  116.     }
  117.     if (!iamserver) {
  118.         bcopy (hisaddr, (char *) &addr.sin_addr, hislen);
  119.         while (connect (sock, /*(char *)*/ &addr, sizeof (addr)) < 0)
  120.             if ( errno == EINTR || errno == ECONNREFUSED) {
  121.                 close (sock);
  122.                 sleep(2);
  123.                 if ((sock = socket (AF_INET, SOCK_STREAM, 0))
  124.                     < 0)
  125.                     error ("socket in connectport");
  126.             } else
  127.                 error ("connect in connectport");
  128.     }
  129.     if ((s = dup(sock)) < 0)
  130.         error("dup");
  131.     if ((inp = fdopen(sock, "r")) == NULL)
  132.         error("fdopen");
  133.     if ((out = fdopen(s, "w")) == NULL)
  134.         error("fdopen");
  135.     setlinebuf(out);
  136. }
  137.  
  138. u_short
  139. hashport (s, port)
  140.     char *s;
  141.     u_short port;
  142. {
  143.     while (*s)
  144.         port = (port << 1) + *s++;
  145.     return (port & 0x7fff);
  146. }
  147.  
  148. /*
  149.  * addr is in network byte order.
  150.  */
  151. u_short
  152. hashaddr(addr, port, len)
  153. u_short port;
  154. char *addr;
  155. {
  156.  
  157.     while (len--)
  158.         port = (port << 1) + *addr++;
  159.     return (port & 0x7fff);
  160. }
  161.  
  162. char *
  163. copyhost(host)
  164. struct hostent *host;
  165. {
  166.     char *ret;
  167.  
  168.     ret = malloc(host->h_length);
  169.     if (ret == NULL)
  170.         error("malloc");
  171.     bcopy(host->h_addr, ret, host->h_length);
  172.  
  173.     return ret;
  174. }
  175.  
  176. /* Compare h1 and h2 (in network byte order).  The network number is
  177.  * more significant than the host number, thus we need to call ntohl().
  178.  */
  179. comparehost(h1, h2, len)
  180. char *h1, *h2;
  181. {
  182.     auto unsigned long l1, l2;
  183.  
  184.     bcopy(h1, &l1, sizeof l1);
  185.     bcopy(h2, &l2, sizeof l2);
  186.     l1 = ntohl(l1);
  187.     l2 = ntohl(l2);
  188.  
  189.     if (l1 < l2)
  190.         return -1;
  191.     else if (l1 > l2)
  192.         return 1;
  193.     return 0;
  194. }
  195.